package com.mxx.common.data.jpa;

import com.mxx.common.core.Pairs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * @Author itzgyw
 * @Date 2020-01-06
 * @Time 15:07
 * @Description:
 */
@NoRepositoryBean
public interface DefaultRepository<T, ID extends Serializable> extends JpaRepository<T, ID>, JpaSpecificationExecutor<T> {

    Optional findById(ID id, String... columns);

    Optional findById(Class voClass, ID id, String... columns);

    Optional<T> findOneAndDetach(Specification<T> spec);

    void saveOfSpecifiedID(T t);

    void saveOfSpecifiedIDNoTx(T entity);

    void saveOfSpecifiedID(List<T> t);

    T saveNoTx(T entity);

    T saveOrUpdate(T entity);

    Optional selectFirst(Specification<T> spec, String... columns);

    Optional selectFirst(Class voClass, Specification<T> spec, String... columns);

    List selectList(Specification<T> spec, String... columns);

    List selectList(String... columns);

    List selectList(Class voClass, String... columns);

    List selectList(Class voClass, Specification<T> spec, String... columns);

    Page selectPage(Pageable pageable, String... columns);

    Page selectPage(Class voClass, Pageable pageable, String... columns);

    Page selectPage(Specification<T> spec, Pageable pageable, String... columns);

    Page selectPage(Class voClass, Specification<T> spec, Pageable pageable, String... columns);

    boolean updateById(T entity);

    int deleteByIds(Collection<ID> ids);

    int updateMulti(UpdateSpecification<T> spec);

    boolean updateOnly(UpdateSpecification<T> spec);

    int deleteMulti(Specification<T> spec);

    boolean deleteOnly(Specification<T> spec);

    boolean exists(Specification<T> spec);

    Class<T> getDomainClass();

    Specification<T> emptySpec();

    ID getIdValue(T entity);

    String idName();
}
